package cn.htsyb.synergy.orm.jpa.criterion;

import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @author lakeside hubin_yuan.410@hotmail.com
 * @version V1.0.0
 * @date 2022/5/11
 * @since 1.0
 */
public class ExpressBuilder<T> {
    private final List<QueryExpress> expresses = new ArrayList<>();

    public static <T> ExpressBuilder<T> instance() {
        return new ExpressBuilder<T>();
    }

    public static <T> ExpressBuilder<T> instance(List<QueryExpress> expresses) {
        return new ExpressBuilder<T>().addAllExpress(expresses);
    }


    public <T> ExpressBuilder<T> addAllExpress(List<QueryExpress> expresses) {
        this.expresses.addAll(expresses);
        return (ExpressBuilder<T>) this;
    }

    public <T> ExpressBuilder<T> addExpressOfEQ(boolean condition, String property, Object compare) {

        if (condition) {
            expresses.add(new QueryExpress(property, QueryExpress.Operator.EQ, compare));
        }
        return (ExpressBuilder<T>) this;
    }

    public <T> ExpressBuilder<T> addExpressOfOperator(boolean condition, String property, QueryExpress.Operator operator, Object compare) {

        if (condition) {
            expresses.add(new QueryExpress(property, operator, compare));
        }
        return (ExpressBuilder<T>) this;
    }

    public <T> ExpressBuilder<T> addExpressOfInOrEq(boolean condition, String property, List<?> compare) {
        if (condition) {
            if (compare.size() > 1) {
                expresses.add(new QueryExpress(property, QueryExpress.Operator.IN, compare));
            } else if (compare.size() == 1) {
                expresses.add(new QueryExpress(property, QueryExpress.Operator.EQ, compare.get(0)));
            }
        }
        return (ExpressBuilder<T>) this;
    }

    public <T> ExpressBuilder<T> addExpressOfBetweenOrEq(boolean condition, String property, List<?> compare) {
        if (condition) {
            if (compare.size() >= 2) {
                if (!ObjectUtils.isEmpty(compare.get(0))) {
                    expresses.add(new QueryExpress(property, QueryExpress.Operator.GTE, compare.get(0)));
                }
                if (!ObjectUtils.isEmpty(compare.get(1))) {
                    expresses.add(new QueryExpress(property, QueryExpress.Operator.LTE, compare.get(1)));
                }
            } else if (compare.size() == 1) {
                expresses.add(new QueryExpress(property, QueryExpress.Operator.EQ, compare.get(0)));
            }

        }
        return (ExpressBuilder<T>) this;
    }

    public List<QueryExpress> build() {
        return expresses;
    }
}
